package com.eadaula05.oficina;

import java.io.BufferedWriter;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Scanner;

import javax.swing.JOptionPane;

public class CadastroAlunoSerial {

	private Scanner entrada;
	private final String enderecoArquivo = "alunos.ser";
	private File arquivo;
	private File log;
	private ObjectInputStream leitor;
	private ObjectOutputStream gravador;
	private HashMap<String, Aluno> alunos;
	private String logText = null;
	private String logName = null;

	public static void main(String[] args) {
		CadastroAlunoSerial cat = new CadastroAlunoSerial();
		cat.iniciar();
	}

	public CadastroAlunoSerial() {
		arquivo = new File(enderecoArquivo);
		log = new File("log.txt");
		alunos = new HashMap<String, Aluno>();
		entrada = new Scanner(System.in);

		iniciar();
	}

	private void iniciar() {
		int opcao = -1;
		try {

			lerArquivo();

			do {
				exibeMenu();
				opcao = opcaoUsuario();
				switch (opcao) {
				case 1: {
					exibirAlunos();
					break;
				}
				case 2: {
					novoAluno();
					break;
				}
				case 3: {
					removerAluno();
					break;
				}
				case 4: {
					limparLog();
					break;
				}
				case 5: {
					break;
				} // Sair
				default: {
					System.out.println("OpÁ„o inexistente.");
					opcao = -1;
				}
				}

			} while (opcao != 5);

			finalizar();

		} catch (IOException ioe) {
			System.out.println("Falha durante a manipulaÁ„o do arquivo.");
		} catch (ClassNotFoundException cnfe) {
			System.out.println("Falha durante convser„o do registro em Aluno.");
		}

		System.out.println("Encerrando..");
		System.exit(0);

	}

	private void finalizar() throws IOException {
		System.out.println("Salvando dados no arquivo..");
		gravarArquivo();
	}

	private void exibeMenu() {
		System.out.println(":: Menu ::\n");
		System.out
				.println(" 1. Ver Alunos\n 2. "
						+ "Adicionar Aluno\n 3. Remover Aluno\n 4. Limpar Log\n 5. Gravar/Sair ");
		System.out.print(">> ");
	}

	private int opcaoUsuario() throws IOException {
		return entrada.nextInt();
	}

	private void exibirAlunos() {
		System.out.println("# Lista de Alunos\n");
		for (Aluno a : alunos.values()) {
			System.out.println("MatrÌcula: " + a.getMatricula());
			System.out.println("Nome: " + a.getNome());
			if (a.getEndereco() != null && !a.getEndereco().isEmpty()) {
				System.out.println("EndereÁo: " + a.getEndereco());
			}
			if (a.getTelefone() != null && !a.getTelefone().isEmpty()) {
				System.out.println("Telefone: " + a.getTelefone());
			}
			System.out.println();
		}
		System.out.println("-----------------------");
	}

	private void novoAluno() {
		System.out.println("Informe matricula, nome, endereco e "
				+ "telefone do aluno, separados por vÌrgula.");
		System.out.print("* Apenas matrÌcula e nome s„o "
				+ "obrigatÛrios. \n>>");
		entrada.nextLine();

		String dados = entrada.nextLine();
		String[] dadosAluno = dados.split(",");
		logName = dadosAluno[1];

		Aluno a = new Aluno(dadosAluno[0], dadosAluno[1]);
		if (dadosAluno.length >= 3) {
			a.setEndereco(dadosAluno[2]);
		}
		if (dadosAluno.length >= 4) {
			a.setTelefone(dadosAluno[3]);
		}

		alunos.put(a.getMatricula(), a);
	}

	private void removerAluno() {
		System.out.print("Informe matricula do aluno que deseja "
				+ "remover.\n>>");
		entrada.nextLine();

		String matricula = entrada.nextLine();

		if (alunos.containsKey(matricula)) {
			Aluno a = alunos.remove(matricula);
			System.out.println("Aluno(a): " + a.getNome() + " removido(a)..");

			logText = " - Aluno(a): " + a.getNome() + " foi removido(a)";
			logActions(logText);
		} else {
			System.out.println("Matricula n„o encontrada..");
		}

	}

	private void lerArquivo() throws IOException, ClassNotFoundException {

		if (arquivo.length() <= 0)
			return;

		System.out.println("Carregando dados do arquivo..");
		leitor = new ObjectInputStream(new FileInputStream(arquivo));
		// String dados = "";
		Aluno temp = null;

		try {

			while ((temp = (Aluno) leitor.readObject()) != null) {
				alunos.put(temp.getMatricula(), temp);
			}

		} catch (EOFException eofe) {
			System.out.println("Arquivo de registros vazio.");
		}
		leitor.close();
		leitor = null;

	}

	private void gravarArquivo() throws IOException {
		if (alunos != null) {
			gravador = new ObjectOutputStream(new FileOutputStream(arquivo,
					false));
			for (Aluno a : alunos.values()) {
				gravador.writeObject(a);

			}
			if (logName != null) {
				logText = " - Aluno(a): " + " " + logName + " "
						+ " foi adicionado(a)";
				logActions(logText);
			}

			gravador.flush();
			gravador.close();
			gravador = null;
		}
	}

	/**
	 * logAction() metodo usado para a criação de logs
	 * 
	 * @param logText
	 */
	private void logActions(String logText) {
		Date data = new Date();
		try {
			BufferedWriter buff = new BufferedWriter(new FileWriter(log, true));
			buff.write("\n>>" + data.toLocaleString() + logText + "\n");
			buff.flush();
			buff.close();

		} catch (IOException ex) {
			System.out.println("Não foi possivel gravar logs");
			ex.printStackTrace();
		}
	}

	/**
	 * limparLog() metodo para limpar o aruivo de logs
	 */
	private void limparLog() {
		// chamada a chanela de confirmação de alteração do arquivo de log
		int x = JOptionPane.showConfirmDialog(null,
				"Tem certeza que deseja apagar dados " + "de log?",
				"Limpar log", 0);

		if (x == 0) {

			try {
				BufferedWriter apagar = new BufferedWriter(new FileWriter(log,
						false));
				apagar.write("");
				apagar.flush();
				apagar.close();
				System.out.println("Arquivo de log apagado com sucesso!");
			} catch (IOException ex) {
				System.out.println("Não foi possivel apagar o arquivo de Log");
				ex.printStackTrace();
			}
		}
	}
} // Final da Classe
